package com.pd.kit;

import redis.clients.jedis.Jedis;

import java.util.Collections;

/**
 * Created by dong peng on 2018/4/22.
 */
public class LockByRedis {

    private static final String LOCK_SUCCESS = "OK";
    private static final Long RELEASE_SUCCESS = 1L;
    private static final String NOT_EXIST = "NX";
    private static final String EXPIRE_TIME = "PX";
    private static final int RETRY_COUNT = 5;

    public static boolean getLock(Jedis jedis, String key, String value, long time) {
        String result = jedis.set(key,value, NOT_EXIST,EXPIRE_TIME,time);
        if(LOCK_SUCCESS.equals(result)) {
            jedis.close();
            return true;
        }else {
            jedis.close();
            return false;
        }
    }

    /**
     * 多次抢锁，超过5次抢不到失败
     * @param jedis
     * @param key
     * @param value
     * @param time
     * @return
     */
    public static boolean getLockMust(Jedis jedis, String key, String value, long time) {
        String result = jedis.set(key,value, NOT_EXIST,EXPIRE_TIME,time);
        int count = 0;
        while (!LOCK_SUCCESS.equals(result) && count < RETRY_COUNT) {
            result = jedis.set(key,value, NOT_EXIST,EXPIRE_TIME,time);
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            count++;
            System.out.println("线程: "+Thread.currentThread()+",获取锁失败,获锁次数{}"+count+" 再次获取锁 key: "+key + " value: "+value);
        }

        if(LOCK_SUCCESS.equals(result)) {
            jedis.close();
            return true;
        }else {
            jedis.close();
            return false;
        }

    }

    public static boolean releaseLock(Jedis jedis, String key, String value) {
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        Object result = jedis.eval(script, Collections.singletonList(key), Collections.singletonList(value));

        if (RELEASE_SUCCESS.equals(result)) {
            jedis.close();
            return true;
        }
        jedis.close();
        return false;
    }
}
